package cn.gyn.gynrpc.core.consumer.http;

import cn.gyn.gynrpc.core.api.RpcException;
import cn.gyn.gynrpc.core.api.RpcRequest;
import cn.gyn.gynrpc.core.api.RpcResponse;
import cn.gyn.gynrpc.core.consumer.HttpInvoker;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * OkHttp Invoker
 */
@Slf4j
public class OkHttpInvoker implements HttpInvoker {
    final static MediaType JSONTYPE = MediaType.get("application/json; charset=utf-8");

    OkHttpClient client;

    public OkHttpInvoker(int timeout) {
        client = new OkHttpClient.Builder()
                .connectionPool(new ConnectionPool(16, 60, TimeUnit.SECONDS))
                .readTimeout(timeout, TimeUnit.MILLISECONDS)
                .writeTimeout(timeout, TimeUnit.MILLISECONDS)
                .connectTimeout(timeout, TimeUnit.MILLISECONDS)
                .retryOnConnectionFailure(true)
                .build();
    }

    @Override
    public RpcResponse post(RpcRequest rpcRequest, String url) {
        String requestString = JSON.toJSONString(rpcRequest);
        log.debug(" ===> post  url = {}, requestString = {}", requestString, url);
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(requestString, JSONTYPE))
                .build();
        try {
            String respJson = client.newCall(request).execute().body().string();
            log.debug(" ===> respJson = " + respJson);
            return JSON.parseObject(respJson, RpcResponse.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public String post(String requestString, String url) {
        log.debug(" ===> post  url = {}, requestString = {}", requestString, url);
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(requestString, JSONTYPE))
                .build();
        try {
            String respJson = client.newCall(request).execute().body().string();
            log.debug(" ===> respJson = " + respJson);
            return respJson;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String get(String url) {
        log.debug(" ===> get url = " + url);
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        try {
            String respJson = client.newCall(request).execute().body().string();
            log.debug(" ===> respJson = " + respJson);
            return respJson;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}


/*public class OkHttpInvoker implements HttpInvoker {
    *//**
     * 三个构建http请求的方法
     * 1、OkHttp
     * 2、HttpClient(Apache HttpComponents 中的一个模块，用于处理HTTP请求和响应)
     * 3、jdk里自带的URLConnection
     * @param request
     * @return
     *//*
    OkHttpClient client;
    final static MediaType JSONTYPE = MediaType.get("application/json;charset=utf-8");

    public OkHttpInvoker(int timeout) {
        client = new OkHttpClient.Builder()
                //连接池，创建最大连接数为16的连接池
                .connectionPool(new ConnectionPool(16, 60, TimeUnit.SECONDS))
                //从服务器取到数据的超时时间
                .readTimeout(timeout, TimeUnit.MILLISECONDS)
                //请求发往服务器的超时时间
                .writeTimeout(timeout, TimeUnit.MILLISECONDS)
                .connectTimeout(timeout, TimeUnit.MILLISECONDS)
                .retryOnConnectionFailure(true)
                .build();
    }

    @Override
    public RpcResponse<?> Post(RpcRequest rpcRequest, String url) {
        String reqJson = JSON.toJSONString(rpcRequest);
        log.debug(" ===> reqJson :" + reqJson);
        //okhttp里的request
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(reqJson, JSONTYPE))
                .build();

        try {
            //不能用toString ，会把整个okhttp3的对象和虚拟地址打印出来，导致反序列化异常， 这里要用string获取内容的字符串
            //String respBody = client.newCall(request).execute().body().string();
            String respBody = client.newCall(request).execute().body().string();
            log.debug(" ===> respJson :" + respBody);
            RpcResponse rpcResponse = JSON.parseObject(respBody, RpcResponse.class);
            return rpcResponse;
        } catch (Exception e) {
            throw new RpcException(e);
        }
    }
}*/
